
use core::arch::{global_asm, naked_asm};

#[allow(dead_code)]
/// dummy function, makes ide feels good.
fn test(_test: &[&i32]) {
    loop{}
}


/// Rusty panic
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: & core::panic::PanicInfo) -> ! {
    loop {}
}


/// Hardware panic
#[unsafe(no_mangle)]
#[allow(dead_code)]
extern "C" fn _panic_handler() {
    loop {}
}


/// Interrupt handler
#[unsafe(no_mangle)]
#[allow(dead_code)]
extern "C" fn _interrupt_handler() {
    //do nothing
}


/// After the rom commands, First Flash Commands.
///
/// # Do:
/// - Cpy .data and .bss from Flash to SRAM.
/// - init GP register
/// - set .bss to zeros
/// - init interrupt
/// - init FPU
/// - init SP register
///
/// # Reason:
/// Though flash is connected to the CPU data
/// bus via MMU, it is read only. so `.data` and
/// `.bss` data should be moved to SRAM.
///
#[unsafe(naked)]
#[unsafe(no_mangle)]
#[unsafe(link_section=".text.entry")]
extern "C" fn _start() {
    naked_asm!(


        // init GP register
        ".option push",
        ".option norelax",
        "la gp, __global_pointer$",
        ".option pop",

        // init SP register
        "la sp,  __stack_top",

        //  init b"li      t0, 0x6000",
        "csrrs   t0, mstatus, t0",
        "la      a0, _edata",
        "la      a2, _end",
        "sub     a2, a2, a0",
        "li      a1, 0",
        "call    memset",

        // // enable Interrupt.
        // "la      t0, _vector_table",
        // "ori     t0, t0, 1",
        // "csrrw   zero, mtvec, t0",

        // // init FPU
        // "li      t0, 0x6000",
        // "csrrs   t0, mstatus, t0",
        ".option push",
        ".option norelax",
        "la a0, _data_start",
        "la a1, _data_lma",
        "la a2, _data_size",
        "call memcpy",
        ".option pop",
        "J main",
    );
}






global_asm!(
    "_vector_table:",
        ".option push",
        ".option norvc",
        "j _panic_handler",

        ".rept 31",
        "j _interrupt_handler",
        /* 31 entries pointing to single interrupt handler */
        // TODO: make everyone work
        ".endr",
        ".option pop",
        ".size _vector_table, .-_vector_table",
);